package ro.gillardon.commons.hotel;

import java.util.ArrayList;
import java.util.List;

import ro.gillardon.commons.Price;
import ro.gillardon.commons.enums.DayType;
import ro.gillardon.commons.enums.Hotel;
import ro.gillardon.commons.enums.RoomType;

/**
 * HotelDetailsWrapper calss is a wrapper class for the prices of the different room types for a hotel.
 *
 * @author lorinczi
 */
public class HotelDetailsWrapper {

  /**
   * Field for the wrapper class.
   */
  private Hotel hotel;
  private Price singleRoomWeekdayPrice;
  private Price doubleRoomWeekdayPrice;
  private Price singleRoomWeekendPrice;
  private Price doubleRoomWeekendPrice;

  /**
   * Instantiates a new HotelDetailsWrapper.
   */
  public HotelDetailsWrapper() {
    super();
  }

  /**
   * Constructor with hotel argument.
   *
   * @param hotel
   */

  public HotelDetailsWrapper(final Hotel hotel) {
    this.hotel = hotel;
  }

  /**
   * Constructor.
   *
   * @param hotel hotel from enum
   * @param singleRoomWeekdayPrice
   * @param doubleRoomWeekdayPrice
   * @param singleRoomWeekendPrice
   * @param doubleRoomWeekendPrice
   */
  public HotelDetailsWrapper(final Hotel hotel, final Price singleRoomWeekdayPrice,
    final Price doubleRoomWeekdayPrice,
    final Price singleRoomWeekendPrice, final Price doubleRoomWeekendPrice) {
    super();
    this.hotel = hotel;
    this.singleRoomWeekdayPrice = singleRoomWeekdayPrice;
    this.doubleRoomWeekdayPrice = doubleRoomWeekdayPrice;
    this.singleRoomWeekendPrice = singleRoomWeekendPrice;
    this.doubleRoomWeekendPrice = doubleRoomWeekendPrice;
  }

  @Override
  public String toString() {
    return "HotelDetailsWrapper [hotel=" + this.hotel + ", singleRoomWeekdayPrice="
      + this.singleRoomWeekdayPrice
      + ", doubleRoomWeekdayPrice=" + this.doubleRoomWeekdayPrice + ", singleRoomWeekendPrice="
      + this.singleRoomWeekendPrice
      + ", doubleRoomWeekendPrice=" + this.doubleRoomWeekendPrice + "]";
  }

  /**
   * Getter for hotel.
   *
   * @return the hotel
   */
  public Hotel getHotel() {
    return this.hotel;
  }

  /**
   * Sets the hotel.
   *
   * @param hotel the new hotel
   */

  public void setHotel(final Hotel hotel) {
    this.hotel = hotel;
  }

  /**
   * Getter for single room weekday price.
   *
   * @return the price for single room during weekday
   */
  public Price getSingleRoomWeekdayPrice() {
    return this.singleRoomWeekdayPrice;
  }

  /**
   * Sets the single room weekday price.
   *
   * @param singleRoomWeekdayPrice the new single room weekday price
   */
  public void setSingleRoomWeekdayPrice(final Price singleRoomWeekdayPrice) {
    this.singleRoomWeekdayPrice = singleRoomWeekdayPrice;
  }

  /**
   * Getter for double room weekday price.
   *
   * @return the price for double room during weekday
   */
  public Price getDoubleRoomWeekdayPrice() {
    return this.doubleRoomWeekdayPrice;
  }

  /**
   * Sets the double room weekday price.
   *
   * @param doubleRoomWeekdayPrice the new double room weekday price
   */
  public void setDoubleRoomWeekdayPrice(final Price doubleRoomWeekdayPrice) {
    this.doubleRoomWeekdayPrice = doubleRoomWeekdayPrice;
  }

  /**
   * Getter for single room weekend price.
   *
   * @return the price for single room during weekend
   */
  public Price getSingleRoomWeekendPrice() {
    return this.singleRoomWeekendPrice;
  }

  /**
   * Sets the single room weekend price.
   *
   * @param singleRoomWeekendPrice the new single room weekend price
   */
  public void setSingleRoomWeekendPrice(final Price singleRoomWeekendPrice) {
    this.singleRoomWeekendPrice = singleRoomWeekendPrice;
  }

  /**
   * Getter for double room weekend price.
   *
   * @return the price for double room during weekend
   */
  public Price getDoubleRoomWeekendPrice() {
    return this.doubleRoomWeekendPrice;
  }

  /**
   * Sets the double room weekend price.
   *
   * @param doubleRoomWeekendPrice the new double room weekend price
   */
  public void setDoubleRoomWeekendPrice(final Price doubleRoomWeekendPrice) {
    this.doubleRoomWeekendPrice = doubleRoomWeekendPrice;
  }

  /**
   * Getter for price based on specified conditions.
   *
   * @param hotelCondition the hotel conditions (roomType, dayType, hotel...)
   * @return the price for specified conditions
   */
  public Price getPrice(final HotelConditions hotelCondition) {

    if (hotelCondition.getRoomType().equals(RoomType.SINGLE)) {
      return getSingleRoomPrice(hotelCondition);
    } else {
      return getDoubleRoomPrice(hotelCondition);
    }
  }

  /**
   * Getter for double room price based on specified conditions (dayType).
   *
   * @return the price for double room based on dayType
   */
  private Price getDoubleRoomPrice(final HotelConditions hotelCondition) {
    if (hotelCondition.getDayType().equals(DayType.WEEKDAY)) {
      return this.doubleRoomWeekdayPrice;
    } else {
      return this.doubleRoomWeekendPrice;
    }
  }

  /**
   * Getter for single room price based on specified conditions (dayType).
   *
   * @return the price for single room based on dayType
   */
  private Price getSingleRoomPrice(final HotelConditions hotelCondition) {
    if (hotelCondition.getDayType().equals(DayType.WEEKDAY)) {
      return this.singleRoomWeekdayPrice;
    } else {
      return this.singleRoomWeekendPrice;
    }
  }

  public List<HotelOfferDetails> getHotelOfferList() {

    List<HotelOfferDetails> results = new ArrayList<HotelOfferDetails>();

    HotelOfferDetails hodSDay = new HotelOfferDetails();
    setHotelOfferDefaults(hodSDay);
    hodSDay.setDayType(DayType.WEEKDAY);
    hodSDay.setRoomType(RoomType.SINGLE);
    hodSDay.setPrice(this.singleRoomWeekdayPrice);
    results.add(hodSDay);

    HotelOfferDetails hodDDay = new HotelOfferDetails();
    setHotelOfferDefaults(hodDDay);
    hodDDay.setDayType(DayType.WEEKDAY);
    hodDDay.setRoomType(RoomType.DOUBLE);
    hodDDay.setPrice(this.doubleRoomWeekdayPrice);
    results.add(hodDDay);

    HotelOfferDetails hodSEnd = new HotelOfferDetails();
    setHotelOfferDefaults(hodSEnd);
    hodSEnd.setDayType(DayType.WEEKEND);
    hodSEnd.setRoomType(RoomType.SINGLE);
    hodSEnd.setPrice(this.singleRoomWeekendPrice);
    results.add(hodSEnd);

    HotelOfferDetails hodDEnd = new HotelOfferDetails();
    setHotelOfferDefaults(hodDEnd);
    hodDEnd.setDayType(DayType.WEEKEND);
    hodDEnd.setRoomType(RoomType.DOUBLE);
    hodDEnd.setPrice(this.doubleRoomWeekendPrice);
    results.add(hodDEnd);

    return results;
  }

  private void setHotelOfferDefaults(final HotelOfferDetails hodSDay) {
    hodSDay.setName(this.hotel.getName());
    hodSDay.setLocation(this.hotel.getCity());
  }
}
